/**
 * 
 */
package org.swing.utility.jai.canvas;

import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.awt.image.BufferedImage;

import org.swing.utility.jai.bean.CellGrid;

/**
 * @author lqnhu
 *
 */
public class GridCanvas extends Canvas {
	private BufferedImage image; // this is where we store what will be painted
	private int cellSize; // the size of each cell in pixels
	private CellGrid cellGrid;
	private boolean cellUnderMouse;

	// Constructor
	public GridCanvas(CellGrid grid, int cellSize) {
		cellGrid = grid;
		this.cellSize = cellSize;
		// add mouse listeners for drawing on the canvas
		addMouseListener(new MouseAdapter() {
			public void mouseReleased(MouseEvent e) {
				draw(e.getX(), e.getY());
			}

			public void mousePressed(MouseEvent e) {
				saveCellUnderMouse(e.getX(), e.getY());
			}
		});
		addMouseMotionListener(new MouseMotionAdapter() {
			public void mouseDragged(MouseEvent e) {
				draw(e.getX(), e.getY());
			}
		});
	}

	// saves the status of the cell underneath the mouse,
	// which allows clicking a cell to make it alive or dead
	public void saveCellUnderMouse(int x, int y) {
		try {
			cellUnderMouse = cellGrid.getCellStatus(x / cellSize, y / cellSize);
		} catch (Exception e) {
		}
	}

	// this sets all cells to dead
	public void clear() {
		cellGrid.clear();
	}

	// sets the status of the given cell to the opposite of
	// what we saved when we clicked.
	//
	// note: this does cause problems with clicking and dragging,
	// since all cells that get drawn on have the status of the
	// first cell clicked on applied.
	public void draw(int x, int y) {
		try {
			cellGrid.setCellStatus(x / cellSize, y / cellSize, !cellUnderMouse);
			repaint();
		} catch (Exception e) {
		}
	}

	// this will create the image if it doesn't exist,
	// and then paint it on the screen.
	public void update(Graphics g) {
		Dimension size = getSize();
		if (image == null) {
			image = (BufferedImage) createImage(size.width, size.height);
		}
		paint(image.getGraphics());
		g.drawImage(image, 0, 0, null);
	}

	// this paints the image of the current game field.
	public void paint(Graphics g) {
		Dimension size = getSize();
		g.setColor(Color.GRAY);
		g.fillRect(0, 0, size.width, size.height);
		// draw the cell lines
		g.setColor(Color.WHITE);
		for (int x = 1; x < cellGrid.width; x++) {
			g.drawLine(x * cellSize - 1, 0, x * cellSize - 1, cellSize
					* cellGrid.height - 1);
		}
		for (int y = 1; y < cellGrid.height; y++) {
			g.drawLine(0, y * cellSize - 1, cellSize * cellGrid.width - 1, y
					* cellSize - 1);
		}
		g.drawImage(image, 0, 0, null);
		// draw the living cells.
		g.setColor(Color.YELLOW);
		for (int x = 0; x < cellGrid.width; x++) {
			for (int y = 0; y < cellGrid.height; y++) {
				if (cellGrid.getCellStatus(x, y)) {
					g.fillRect(x * cellSize, y * cellSize, cellSize - 1,
							cellSize - 1);
				}
			}
		}
	}

	// kick off a new generation
	public void newGen() {
		cellGrid.newGeneration();
	}
}
